home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1996 #6 / Amiga Plus CD - 1996 - No. 06.iso / pd / programmierung / programmers / loadmod.a < prev    next >
Text File  |  1996-06-23  |  10KB  |  448 lines

  1. ;    (Octa)MED module load routines, by Teijo Kinnunen
  2. ;    MED V3.00 module support added        22-Jan-1991
  3. ;    upgraded for V3.20 (OctaMED V2.00)    02-Aug-1991
  4. ;    and for OctaMED Pro V3.00        02-Apr-1992
  5. ;    (bug fix)                31-May-1992
  6. ;    OctaMED Pro V5 support (MMD2)        18-May-1993
  7. ;    OctaMED Pro V6 support (cmd pages)    16-Jan-1995
  8. ;    2 bug fixes (Thanks to Peter Kunath.)    14-Feb-1995
  9. ;    V7 support                20-Sep-1995
  10. ;    FastMem loading                26-Nov-1995
  11. ;    MMD3 recognition            04-Dec-1995
  12. ;    RequiredPlayRoutine            09-Jan-1996
  13. ;    Didn't reloc MMD3s correctly...        17-Jan-1996
  14. ;    FastMemPlayRecommended            29-Jan-1996
  15. ;    Fixed MMD0 multi-module reloc error    25-Apr-1996
  16.  
  17. ;    $VER: loadmod_a 7.0 (25.4.1996)
  18.  
  19. ;    Function: d0 = _LoadModule(a0)
  20. ;    a0 = module name
  21. ;    d0 = pointer to loaded module, zero if load failed
  22.  
  23.     XDEF    _LoadModule,_LoadModule_Fast
  24.     XDEF    _UnLoadModule
  25.     XDEF    _RelocModule
  26.     XDEF    _RequiredPlayRoutine
  27.     XDEF    _FastMemPlayRecommended
  28.  
  29. mmd_songinfo    EQU    8
  30. mmd_blockarr    EQU    16
  31. mmd_expdata    EQU    32
  32. mmd_songsleft    EQU    51
  33. msng_numblocks    EQU    504
  34. msng_pseqs    EQU    508
  35. msng_flags    EQU    767
  36. msng_flags2    EQU    768
  37. msng_numsamples    EQU    787
  38.  
  39.         CODE
  40.  
  41. _LoadModule    move.l    d7,-(sp)
  42.         moveq    #0,d7
  43.         bsr.s    LoadMod
  44.         move.l    (sp)+,d7
  45.         rts
  46.  
  47. _LoadModule_Fast
  48.         move.l    d7,-(sp)
  49.         moveq    #1,d7
  50.         bsr.s    LoadMod
  51.         move.l    (sp)+,d7
  52.         rts
  53.  
  54. ;if D7 = 1, load to Fast Mem always
  55. LoadMod:    movem.l a2-a4/a6/d2-d6,-(sp)
  56.         suba.l    a2,a2
  57.         moveq    #0,d6        ;d6 = return value (zero = error)
  58.         move.l  a0,a4        ;a4 = module name
  59.         movea.l 4.w,a6
  60.         lea     dosname(pc),a1
  61.         moveq    #0,d0
  62.         jsr     -$228(a6)    ;OpenLibrary()
  63.         tst.l   d0
  64.         beq     xlm1
  65.         move.l  d0,a3        ;a3 = DOSBase
  66.         move.l  d0,a6
  67.         move.l  a4,d1        ;name = d1
  68.         move.l  #1005,d2    ;accessmode = MODE_OLDFILE
  69.         jsr     -$1e(a6)    ;Open()
  70.         move.l  d0,d4        ;d4 = file handle
  71.         beq     xlm2
  72.         move.l  d4,d1
  73.         moveq   #0,d2
  74.         moveq   #1,d3        ;OFFSET_END
  75.         jsr     -$42(a6)    ;Seek(fh,0,OFFSET_END)
  76.         tst.l    d0
  77.         bmi.w    xlm3        ;-1 = error
  78.         move.l  d4,d1
  79.         moveq    #-1,d3        ;OFFSET_BEGINNING
  80.         jsr     -$42(a6)    ;Seek(fh,0,OFFSET_BEGINNING)
  81.         move.l  d0,d5        ;d5 = file size
  82.         bmi.w    xlm3
  83.         moveq    #1,d1        ;alloc mem for beginning
  84.         moveq    #6*4,d0
  85.         movea.l    4.w,a6
  86.         jsr    -$c6(a6)    ;AllocMem
  87.         tst.l    d0
  88.         beq.w    xlm3
  89.         move.l    d0,a2
  90.         move.l    d4,d1
  91.         move.l    a2,d2
  92.         moveq    #6*4,d3        ;read beginning of the mod..
  93.         move.l    a3,a6
  94.         jsr    -$2a(a6)    ;Read...
  95.         cmp.l    d3,d0
  96.         bne.w    xlm3        ;error
  97.         cmp.l    #'MMD3',(a2)    ;Soundstudio module using mixing?
  98.         beq.s    id_ok
  99.         cmp.l    #'MMD2',(a2)    ;Pro V5 module?
  100.         beq.s    id_ok
  101.         cmp.l    #'MMD1',(a2)    ;Pro module?
  102.         beq.s    id_ok
  103.         cmp.l   #'MMD0',(a2)
  104.         bne.s   xlm3        ;this is not a module!!!
  105. id_ok        btst    #0,20(a2)    ;test mmdflags of the module
  106.         beq.s    1$
  107.         moveq    #1,d7        ;Fast Mem
  108. 1$        movea.l    4.w,a6        ;free the 24-byte buffer
  109.         moveq    #6*4,d0
  110.         move.l    a2,a1
  111.         jsr    -$d2(a6)    ;FreeMem()
  112.         suba.l    a2,a2
  113.         move.l  d4,d1
  114.         moveq    #0,d2
  115.         moveq    #-1,d3        ;OFFSET_BEGINNING
  116.         move.l    a3,a6
  117.         jsr     -$42(a6)    ;Seek(fh,0,OFFSET_BEGINNING)
  118.         tst.l    d0
  119.         bmi.s    xlm3        ;seek error
  120.         movea.l 4.w,a6
  121.         move.l    d5,d0
  122.         moveq   #1,d1        ;mem type: PUBLIC
  123.         tst.b    d7        ;force Fast Mem
  124.         bne.s    2$
  125.         moveq    #3,d1        ;mem type: PUBLIC|CHIP
  126. 2$        jsr     -$c6(a6)    ;AllocMem()
  127.         tst.l   d0
  128.         beq.s   xlm3
  129.         move.l  d0,a4        ;a4 = pointer to module
  130.         move.l  d4,d1    ;file
  131.         move.l  d0,d2    ;buffer
  132.         move.l  d5,d3    ;length
  133.         move.l  a3,a6
  134.         jsr     -$2a(a6)    ;Read()
  135.         cmp.l   d5,d0
  136.         bne.s   xlm4        ;something wrong...
  137.         movea.l a4,a0
  138.         bsr.w   _RelocModule
  139.         move.l  a4,d6        ;no error...
  140.         bra.s   xlm3
  141. xlm4        move.l  a2,a1        ;error: free the memory
  142.         move.l  d5,d0
  143.         movea.l 4.w,a6
  144.         jsr     -$d2(a6)    ;FreeMem()
  145. xlm3        move.l    a2,d0        ;24-byte buffer exists?
  146.         beq.s    1$
  147.         movea.l    4.w,a6
  148.         moveq    #6*4,d0
  149.         move.l    a2,a1
  150.         jsr    -$d2(a6)    ;FreeMem()
  151. 1$        move.l  a3,a6        ;close the file
  152.         move.l  d4,d1
  153.         jsr     -$24(a6)    ;Close(fhandle)
  154. xlm2        move.l  a3,a1        ;close dos.library
  155.         movea.l 4,a6
  156.         jsr     -$19e(a6)
  157. xlm1        move.l  d6,d0        ;push return value
  158.         movem.l (sp)+,a2-a4/a6/d2-d6    ;restore registers
  159.         rts            ;and exit...
  160. dosname        dc.b    'dos.library',0
  161.  
  162. ;    Function: _RelocModule(a0)
  163. ;    a0 = pointer to module
  164.  
  165. ; This function is a bit strangely arranged around the small reloc-routine.
  166. reloci        move.l    24(a2),d0
  167.         beq.s    xloci
  168.         movea.l    d0,a0
  169.         moveq   #0,d0
  170.         move.b  msng_numsamples(a1),d0    ;number of samples
  171.         subq.b  #1,d0
  172. relocs        bsr.s   relocentr
  173.         move.l    -4(a0),d3    ;sample ptr
  174.         beq.s    nosyn
  175.         move.l    d3,a3
  176.         tst.w    4(a3)
  177.         bpl.s    nosyn        ;type >= 0
  178.         move.w    20(a3),d2    ;number of waveforms
  179.         lea    278(a3),a3    ;ptr to wf ptrs
  180.         subq.w    #1,d2
  181. relsyn        add.l    d3,(a3)+
  182.         dbf    d2,relsyn
  183. nosyn        dbf     d0,relocs
  184. xloci        rts
  185. norel        addq.l    #4,a0
  186.         rts
  187. relocentr    tst.l   (a0)
  188.         beq.s   norel
  189.         add.l   d1,(a0)+
  190.         rts
  191. _RelocModule:
  192.         movem.l    a2-a4/d2-d4,-(sp)
  193.         movea.l a0,a2
  194.         move.l  a2,d1        ;d1 = ptr to start of module
  195.         bsr.s    relocp
  196.         movea.l mmd_songinfo(a2),a1
  197.         bsr.s    reloci
  198.         move.b    mmd_songsleft(a2),d4
  199. rel_lp        bsr.s    relocb
  200.         cmp.b    #'T',3(a2)
  201.         beq.s    norelmmd2
  202.         cmp.b    #'2',3(a2)    ;MMD2?
  203.         bcs.s    norelmmd2
  204.         bsr.w    relocmmd2sng
  205. norelmmd2    move.l    mmd_expdata(a2),d0    ;extension struct
  206.         beq.s    rel_ex
  207.         move.l    d0,a0
  208.         bsr.s    relocentr    ;ptr to next module
  209.         bsr.s    relocentr    ;InstrExt...
  210.         addq.l    #4,a0        ;skip sizes of InstrExt
  211. ; We reloc the pointers of MMD0exp, so anybody who needs them can easily
  212. ; read them.
  213.         bsr.s    relocentr    ;annotxt
  214.         addq.l    #4,a0        ;annolen
  215.         bsr.s    relocentr    ;InstrInfo
  216.         addq.l    #8,a0
  217.         bsr.s    relocentr    ;rgbtable (not useful for most people)
  218.         addq.l    #4,a0        ;skip channelsplit
  219.         bsr.s    relocentr    ;NotationInfo
  220.         bsr.s    relocentr    ;songname
  221.         addq.l    #4,a0        ;skip song name length
  222.         bsr.s    relocentr    ;MIDI dumps
  223.         bsr.s    relocmdd
  224.         bsr.s    relocentr    ;mmdinfo
  225.         bsr.s    relocentr    ;mmdrexx
  226.         bsr.w    relocrx
  227.         bsr.s    relocentr    ;mmdcmd3x
  228.         bsr.w    reloccmd3x
  229.         subq.b    #1,d4        ;songs left..?
  230.         bcs.s    rel_ex
  231.         move.l    d0,a0
  232.         move.l    (a0),d0
  233.         beq.s    rel_ex
  234.         move.l    d0,a2
  235.         bsr.s    relocp
  236.         movea.l 8(a2),a1
  237.         bra.s    rel_lp
  238. rel_ex        movem.l    (sp)+,d2-d4/a2-a4
  239.         rts
  240.  
  241. relocp        lea    mmd_songinfo(a2),a0
  242.         bsr.w    relocentr
  243.         addq.l    #4,a0
  244.         bsr.w    relocentr
  245.         addq.l    #4,a0
  246.         bsr.w    relocentr
  247.         addq.l    #4,a0
  248.         bra.w    relocentr
  249.  
  250. relocb        move.l    mmd_blockarr(a2),d0
  251.         beq.s    xlocb
  252.         movea.l    d0,a0
  253.         move.w  msng_numblocks(a1),d0
  254.         subq.b  #1,d0
  255. rebl        bsr    relocentr
  256.         dbf     d0,rebl
  257.         cmp.b    #'T',3(a2)    ;MMD0 (= MCNT)
  258.         beq.s    xlocb
  259.         cmp.b    #'1',3(a2)    ;test MMD type
  260.         bge.w    relocbi
  261. xlocb        rts
  262.  
  263. relocmdd    movem.l    d0/a0,-(sp)
  264.         tst.l    -(a0)
  265.         beq.s    xlocmdd
  266.         movea.l    (a0),a0
  267.         move.w    (a0),d0        ;# of msg dumps
  268.         addq.l    #8,a0
  269. 1$        beq.s    xlocmdd
  270.         bsr    relocentr
  271.         bsr.s    relocdmp
  272.         subq.w    #1,d0
  273.         bra.s    1$
  274. xlocmdd        movem.l    (sp)+,d0/a0
  275.         rts
  276.  
  277. relocrxtrig    movem.l    d0/a0,-(sp)
  278.         subq.l    #4,a0
  279. 2$        move.l    (a0),d0
  280.         beq.s    1$
  281.         move.l    d0,a0
  282.         addq.l    #8,a0
  283.         bsr    relocentr    ;command name
  284.         bsr    relocentr    ;port name
  285.         move.l    d0,a0
  286.         bra.s    2$
  287. 1$        movem.l    (sp)+,d0/a0
  288.         rts
  289.  
  290. relocrx        movem.l    d0/a0,-(sp)
  291.         move.l    -(a0),d0
  292.         beq.s    1$
  293.         move.l    d0,a0
  294.         addq.l    #4,a0        ;skip res, trigcmdlen
  295.         bsr    relocentr
  296.         bsr.s    relocrxtrig
  297. 1$        movem.l    (sp)+,d0/a0
  298.         rts
  299.  
  300. reloccmd3x    movem.l    d0/a0,-(sp)
  301.         move.l    -(a0),d0
  302.         beq.s    1$
  303.         move.l    d0,a0
  304.         addq.l    #4,a0    ;skip struct_vers, pad, num_of_settings
  305.         bsr    relocentr    ;ctrlr_types
  306.         bsr    relocentr    ;ctrlr_numbers
  307. 1$        movem.l    (sp)+,d0/a0
  308.         rts
  309.  
  310. relocdmp    move.l    -4(a0),d3
  311.         beq.s    xlocdmp
  312.         exg.l    a0,d3        ;save
  313.         addq.l    #4,a0
  314.         bsr    relocentr    ;reloc data pointer
  315.         move.l    d3,a0        ;restore
  316. xlocdmp        rts
  317.  
  318. relocbi        move.w    msng_numblocks(a1),d0
  319.         move.l    a0,a3
  320. biloop        subq.w    #1,d0
  321.         bmi.s    xlocdmp
  322.         move.l    -(a3),a0
  323.         addq.l    #4,a0
  324.         bsr    relocentr    ;BlockInfo ptr
  325.         tst.l    -(a0)
  326.         beq.s    biloop
  327.         move.l    (a0),a0
  328.         bsr    relocentr    ;hldata
  329.         bsr    relocentr    ;block name
  330.         addq.l    #4,a0        ;skip blocknamelen
  331.         bsr    relocentr    ;pagetable
  332.         tst.l    -(a0)
  333.         bne.s    relocpgtbl
  334.         bra.s    biloop
  335. ; take care of the new features of MMD2s
  336. relocmmd2sng    move.l    mmd_songinfo(a2),a0
  337.         lea    msng_pseqs(a0),a0
  338.         bsr    relocentr    ;playseqtable
  339.         bsr    relocentr    ;sectiontable
  340.         bsr    relocentr    ;trackvols
  341.         addq.l    #4,a0
  342.         bsr    relocentr    ;trackpans
  343.         move.w    -6(a0),d0    ;numpseqs
  344.         move.l    -20(a0),a0    ;get back to playseqtable
  345.         subq.w    #1,d0
  346. psqtblloop    bsr    relocentr
  347.         dbf    d0,psqtblloop
  348.         rts
  349. relocpgtbl    movea.l    (a0),a4        ;page table list hdr
  350.         move.w    (a4),d2
  351.         subq.w    #1,d2
  352.         lea    4(a4),a0
  353. pgtblloop    bsr    relocentr
  354.         dbf    d2,pgtblloop
  355.         bra    biloop
  356.  
  357.  
  358. ;    Function: _UnLoadModule(a0)
  359. ;    a0 = pointer to module
  360. _UnLoadModule:
  361.         move.l  a6,-(sp)
  362.         move.l  a0,d0
  363.         beq.s   xunl
  364.         movea.l 4,a6
  365.         move.l  4(a0),d0
  366.         beq.s   xunl
  367.         movea.l a0,a1
  368.         jsr     -$d2(a6)    ;FreeMem()
  369. xunl        move.l    (sp)+,a6
  370.         rts
  371.  
  372. ;    Function: _RequiredPlayRoutine(a0)
  373. ;    a0 = pointer to module
  374. ;    Returns:
  375. ;        0 = 4 channel routine (or no module)
  376. ;        1 = 5-8 channel routine
  377. ;        2 = mixing routine
  378.  
  379. _RequiredPlayRoutine:
  380.         move.l    a0,d0
  381.         beq.s    3$
  382.         move.l    8(a0),a0    ;song struct
  383.         tst.b    msng_flags2(a0)    ;mixing?
  384.         bmi.s    2$
  385.         btst    #6,msng_flags(a0) ;5-8 channel?
  386.         bne.s    1$
  387. 3$        moveq    #0,d0
  388.         rts
  389. 1$        moveq    #1,d0
  390.         rts
  391. 2$        moveq    #2,d0
  392.         rts
  393.  
  394. ;    Function: _FastMemPlayRecommended(a0)
  395. ;    a0 = pointer to module
  396. ;    Returns:
  397. ;        0 = plays perfectly without FastMemPlay
  398. ;        1 = may not play perfectly without FastMemPlay
  399.  
  400. _FastMemPlayRecommended:
  401.         movem.l    d2/a2,-(sp)
  402.         move.l    a0,d1
  403.         beq.s    fmpr_ret0
  404.         movea.l    mmd_songinfo(a0),a1
  405.         moveq    #0,d1
  406.         move.b    msng_numsamples(a1),d1
  407.         move.l    24(a0),d0    ;sample array
  408.         beq.s    fmpr_nosamples
  409.         movea.l    d0,a1
  410.         move.l    d1,d0
  411.         subq.l    #1,d0
  412. 1$        move.l    (a1)+,d2
  413.         beq.s    2$
  414.         movea.l    d2,a2        ;instrument address
  415.         move.l    (a2),d2        ;length
  416.         swap    d2        ;upper word...
  417.         lsr.w    #1,d2
  418.         bne.s    fmpr_ret1    ;length >= 131072
  419. 2$        dbra    d0,1$
  420. fmpr_nosamples    move.l    mmd_expdata(a0),d0
  421.         beq.s    fmpr_ret0
  422.         movea.l    d0,a1
  423.         move.l    4(a1),d0    ;exp_smp
  424.         beq.s    fmpr_ret0
  425.         move.w    8(a1),d1
  426.         beq.s    fmpr_ret0
  427.         move.w    10(a1),d2
  428.         cmp.w    #18,d2
  429.         blt.s    fmpr_ret0    ;no long repeat
  430.         movea.l    d0,a1
  431.         subq.w    #1,d1
  432. 1$        move.l    10(a1),d0
  433.         or.l    14(a1),d0
  434.         lsr.l    #1,d0
  435.         bcs.s    fmpr_ret1    ;odd... return 1
  436.         swap    d0
  437.         tst.w    d0
  438.         bne.s    fmpr_ret1    ;start/len >= 131072
  439.         adda.w    d2,a1
  440.         dbra    d1,1$
  441. fmpr_ret0    moveq    #0,d0
  442. fmpr_ret    movem.l    (sp)+,d2/a2
  443.         rts
  444. fmpr_ret1    moveq    #1,d0
  445.         bra.s    fmpr_ret
  446.  
  447.         END
  448.